package main

import (
	"fmt"
	"image"
	"path/filepath"

	"demserver/src/elevation"
)

func main() {
	// Use the actual GeoTIFF file
	filename := "./demdata/ClipResult.tif"

	// Get absolute path to the file
	absPath, err := filepath.Abs(filename)
	if err != nil {
		fmt.Printf("Failed to get absolute path: %v\n", err)
		return
	}

	fmt.Printf("Loading GeoTIFF file: %s\n", absPath)
	geoTiff, err := elevation.LoadGeoTIFF(absPath)
	if err != nil {
		fmt.Printf("Failed to load GeoTIFF: %v\n", err)
		return
	}
	fmt.Println("GeoTIFF loaded successfully")
	fmt.Printf("Image type: %T\n", geoTiff.Image)

	// Test coordinate conversion with the provided coordinates
	testPoints := []struct {
		key      string
		lat      float64
		lon      float64
		expected float64
	}{
		{"103.54607363636364-31.02659757575758", 31.02659757575758, 103.54607363636364, 780.2126995110525},
		{"103.572044-31.037039", 31.037039, 103.572044, 806.0841527110774},
		{"103.5912788-31.0304264", 31.0304264, 103.5912788, 773.8375500820072},
		{"103.59295529411764-31.01249117647059", 31.01249117647059, 103.59295529411764, 739.7479166299393},
		{"103.607449-31.0013281", 31.0013281, 103.607449, 727.5249991936447},
		{"103.61049-30.99902", 30.99902, 103.61049, 731.2953275545822},
		{"103.6209426-30.9973639", 30.9973639, 103.6209426, 721.5718677856261},
		{"103.622048-30.9965182", 30.9965182, 103.622048, 726.0016953857438},
		{"103.6189289-30.9946229", 30.9946229, 103.6189289, 721.8344924017556},
		{"103.6207096-30.9944371", 30.9944371, 103.6207096, 721.5469676427813},
		{"103.6017582-30.9830936", 30.9830936, 103.6017582, 718.2758389407071},
		{"103.6020184-30.9834017", 30.9834017, 103.6020184, 716.2884784266679},
		{"104.18999-31.09466", 31.09466, 104.18999, 506.7021200994833},
		{"103.64307-30.66861", 30.66861, 103.64307, 551.6861936104318},
		{"104.04-30.67", 30.67, 104.04, 493.5921921968492},
		{"104.99765666666666-30.903603333333333", 30.903603333333333, 104.99765666666666, 430.16075042601153},
		{"105.03068-30.82763", 30.82763, 105.03068, 426.22719400908005},
		{"104.01804-30.43845", 30.43845, 104.01804, 1457.7227145056859},
		{"103.78443-30.12122", 30.12122, 103.78443, 422.80135518608773},
		{"104.05738692307692-30.07204961538461", 30.07204961538461, 104.05738692307692, 506.6227417060706},
		{"104.24654-29.93688", 29.93688, 104.24654, 372.7077051609116},
		{"105.08767-30.26496", 30.26496, 105.08767, 1457.9382575255709},
	}

	fmt.Println("\nTesting coordinate conversion and elevation retrieval:")
	fmt.Printf("%-40s %-15s %-15s %-15s %-15s %-10s\n", "Coordinate", "Lat", "Lon", "Expected", "Actual", "Error")

	for _, point := range testPoints {
		x, y, err := geoTiff.LatLonToPixel(point.lat, point.lon)
		if err != nil {
			fmt.Printf("Failed to convert coordinates (%f, %f): %v\n", point.lat, point.lon, err)
			continue
		}

		// Check if coordinates are within bounds
		if x < 0 || y < 0 || x >= float64(geoTiff.Width) || y >= float64(geoTiff.Height) {
			fmt.Printf("%-40s %-15.6f %-15.6f %-15s %-15s %-10s\n", point.key, point.lat, point.lon, "Out of bounds", "Out of bounds", "N/A")
			continue
		}

		// Get elevation value
		elevationVal, err := geoTiff.GetElevation(x, y)
		if err != nil {
			fmt.Printf("Failed to get elevation at (%f, %f): %v\n", x, y, err)
			continue
		}

		errorValue := elevationVal - point.expected
		fmt.Printf("%-40s %-15.6f %-15.6f %-15.6f %-15.6f %-10.6f\n", point.key, point.lat, point.lon, point.expected, elevationVal, errorValue)
	}

	// Analyze pixel values around a specific point
	fmt.Println("\nDetailed pixel analysis for one point:")
	lat := 31.02659757575758
	lon := 103.54607363636364
	x, y, _ := geoTiff.LatLonToPixel(lat, lon)
	xInt := int(x)
	yInt := int(y)

	if grayImg, ok := geoTiff.Image.(*image.Gray16); ok {
		fmt.Printf("Pixel values around (%d, %d):\n", xInt, yInt)
		for dy := -1; dy <= 1; dy++ {
			for dx := -1; dx <= 1; dx++ {
				px := xInt + dx
				py := yInt + dy

				if px >= 0 && py >= 0 && px < geoTiff.Width && py < geoTiff.Height {
					value := grayImg.Gray16At(px, py)
					var processedValue float64
					if value.Y > 32767 {
						processedValue = float64(value.Y)
					} else {
						processedValue = float64(int16(value.Y))
					}
					fmt.Printf("  Pixel (%d, %d): Raw=%d, Processed=%.2f\n", px, py, value.Y, processedValue)
				}
			}
		}
	}
}
